String.prototype.wrap = function (tag, attrs) {
    attrs = (attrs || {});
    var atr = Object.keys(attrs).map(it => it + "='" + attrs[it] + "'").join(" ")
    if (atr) {
        atr = " " + atr;
    }
    return "<" + tag + atr + ">" + this + "</" + tag + ">"
}

Object.defineProperty(Array.prototype, "unwind", {
    value() {
        var ret = [];
        this.forEach(wai => {
            wai.forEach(it => {
                ret.push(it);
            });
        });
        return ret;
    }, enumerable: false, configurable: true, writable: true
});

var jv = {};

jv.joinUrl = function (v) {
    var paths = Array.from(arguments)
    if (!paths.length) return "";

    if (v && v.Type == "array") {
        paths = v;
    }

    var head = paths[0].toLowerCase()
    if (head.startsWith("http://") || head.startsWith("https://")) {
        paths.shift()
    } else if (head.startsWith("//")) {
        paths.shift();
    } else {
        head = "";
    }


    var list = [];
    paths
        .filter(it => it)
        .map(it => {
            return it.split('/')
                .filter(it => it && (it != "."))
        })
        .unwind()
        .forEach(it => {
            if (it == "..") {
                if (list.pop() == null) {
                    throw new Error("url地址层级溢出")
                }
                return
            }

            list.push(it);
        })

    return head + list.map(it => {
        return "/" + it
    }).join("")
}


Array.prototype.sum = function () {
    var sum = 0;
    for (var i = 0; i < this.length; i++) {
        sum += this[i];
    }
    return sum;
};

function gen(data) {
    return data.map(it => productLine(it)).join("\n")
}

function productLine(pl) {
    pl.total = pl.routeGroups.map(it => it.routes.length).sum();
    return ((pl.name + ": (" + pl.total + ")").wrap("ti") + pl.routeGroups.map(it => getRoutes(it)).join("")).wrap("pl") + "<n></n>"
}


function getRoutes(git) {
    var t = git.name ? ((git.name + " (" + git.routes.length + ")").wrap("git") + "⟼ ") : "";
    return (t + git.routes.map(it => web ? web_item(it) : java_item(it)).join("")).wrap("row")
}

function web_item(service) {
    var css = ""
    if (service.online) {
        css = "sp"
    }

    var j = {"class": css || "", target: "_blank"};

    if (service.name.startsWith(".")) {
        service.name = service.name.slice(1)
    }

    if (service.name.startsWith("/")) {
        service.name = service.name.slice(1)
    }

    if (service.name.endsWith("/")) {
        service.name = service.name.slice(0, -1)
    }

    var host = window.location.protocol + "//" + window.location.hostname

    if (service.port && service.port != 80) {
        host += ":" + service.port;
    } else if (window.location.port != 80) {
        host += ":" + window.location.port
    }

    j.href = jv.joinUrl(host, service.name);

    return service.name.wrap("a", j)
}

function java_item(service) {
    var css = ""
    if (service.online) {
        css = "sp"
    }

    var j = {"class": css || "", target: "_blank"};

    if (service.name.endsWith("-gateway")) {
        j["class"] += " gateway";
        service.name = service.name.slice(0, 0 - "-gateway".length)
    }

    if (service.name.startsWith(".")) {
        service.name = service.name.slice(1)
    }

    if (service.name.startsWith("/")) {
        service.name = service.name.slice(1)
    }

    if (service.name.endsWith("/s")) {
        service.name = service.name.slice(0, -1)
    }

    if (service.path && service.path.startsWith("http://")) {
        j.href = service.path + "/doc.html"
    } else {
        j.href = "./" + service.name + "/doc.html"
    }

    return service.name.wrap("a", j)
}

